package org.campuscontent.ui;

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.io.Serializable;
import java.util.EventObject;

import javax.swing.DefaultCellEditor;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;

import org.campuscontent.model.AutomataConstants;
import org.jgraph.JGraph;
import org.jgraph.graph.CellView;
import org.jgraph.graph.EdgeView;
import org.jgraph.graph.GraphCellEditor;
import org.jgraph.graph.PortView;

public class EdgeMaskView extends EdgeView implements AutomataConstants
{
    public EdgeMaskView( Object cell )
    {
        super( cell );
    }
    
    public void setLabelPosition(Point2D point)
    {
    	super.setLabelPosition( point );
    }

    public GraphCellEditor getEditor()
    {
        return cellEditor;
    }
    
    public Point2D getLabelPosition()
    {
    	return super.labelPosition;
    }
    
    public void setSource( PortView source )
    {
        this.source = source;
    }

    public void setTarget( PortView target )
    {
        this.target = target;
    }

    public CellView getSource()
    {
        return this.source;
    }
    
    public CellView getTarget()
    {
        return this.target;
    }
    
    protected static transient GraphCellEditor cellEditor = new AutomataEdgeEditor( new JTextField() );

    public static class Verifier extends InputVerifier
    {
        public boolean verify( JComponent input )
        {
            if ( true ) return true;

            JTextField tf = (JTextField) input;
            return "pass".equals( tf.getText() );
        }
    }

    public static class MaskEditor extends JTextField
    {
        public MaskEditor()
        {
            super( 10 );

            setInputVerifier( new Verifier() );
        }
    }

    public static class AutomataEdgeEditor extends DefaultCellEditor implements GraphCellEditor
    {
        // protected JComponent editorComponent;
        // protected EditorDelegate delegate;
        // protected int clickCountToStart = 1;

        protected transient EditorDelegate mixDelegate;
        protected transient JGraph graph;
        protected transient JTextField left;
        protected transient JTextField right;

        public AutomataEdgeEditor( final JTextField field )
        {
            super( field ); // dummy

            left  = new JTextField( 10 );
            right = new JTextField( 10 );

            editorComponent = new JPanel( new FlowLayout( FlowLayout.CENTER ) );
            this.clickCountToStart  = 2;

            mixDelegate = new EditorDelegate()
            {
                public void setValue( Object value )
                {
                    if ( value != null )
                    {
                        // System.out.println( "EditorDelegate::setValue() = " +
                        // value );
                    }
                }

                public Object getCellEditorValue()
                {
                    String strLeft = left.getText();
                    String strRight = right.getText();

                    // if ( strLeft != null && strRight != null &&
                    // !strLeft.equals( "" ) && !strRight.equals( "" ) )
                    if ( strLeft != null && strRight != null )
                    {
                        if ( strLeft.equals( "" ) && strRight.equals( "" ) ) 
                        	return "empty";
                        else if(strLeft.equals(""))
                        	return	strRight;
                        else if(strRight.equals(""))
                        	return	strLeft;
                        else
                        	return strLeft + GLUE + SEPARATOR + GLUE + strRight;
                    }

                    return "";
                }
            };

            left.addActionListener( mixDelegate );
            right.addActionListener( mixDelegate );

            editorComponent.add( left );
            editorComponent.add( new JLabel( GLUE ) );
            editorComponent.add( new JLabel( SEPARATOR ) );
            editorComponent.add( new JLabel( GLUE ) );
            editorComponent.add( right );
        }
        
        public static String getLinkName( String left, String right )
        {
            return left + SEPARATOR + right;
        }

        //
        // GraphCellEditor Interface
        //
        public Component getGraphCellEditorComponent( JGraph graph, Object value, boolean isSelected )
        {
            this.graph = graph;

            String stringValue = graph.convertValueToString( value );

            if ( stringValue != null && stringValue.indexOf( SEPARATOR ) != -1 )
            {
                String[] items = stringValue.split( "\\" + SEPARATOR );

                String leftValue = "";
                String rightValue = "";

                if ( stringValue.indexOf( SEPARATOR ) == 0 ) // there's not
                                                                // left text
                {
                    leftValue = "";
                    rightValue = items[ 1 ].trim();
                }
                else if ( stringValue.indexOf( SEPARATOR ) == stringValue.length() - SEPARATOR.length() ) // there's
                                                                                                            // not
                                                                                                            // left
                                                                                                            // text
                {
                    leftValue = items[ 0 ].trim();
                    rightValue = "";
                }
                else
                {
                    leftValue = items[ 0 ].trim();
                    rightValue = items[ 1 ].trim();
                }

                left.setText( leftValue );
                right.setText( rightValue );
            }
            else
            {
                left.setText( stringValue );
                right.setText( "" );
            }

            mixDelegate.setValue( stringValue );
            if ( editorComponent instanceof JPanel )
            {
                left.selectAll();
                right.selectAll();

                left.requestFocus();
            }

            return editorComponent;
        }

        public Component getComponent()
        {
            return editorComponent;
        }

        public void setClickCountToStart( int count )
        {
            clickCountToStart = count;
        }

        public int getClickCountToStart()
        {
            return clickCountToStart;
        }

        public Object getCellEditorValue()
        {
            return mixDelegate.getCellEditorValue();
        }

        public boolean isCellEditable( EventObject anEvent )
        {
            return mixDelegate.isCellEditable( anEvent );
        }

        public boolean shouldSelectCell( EventObject anEvent )
        {
            return mixDelegate.shouldSelectCell( anEvent );
        }

        public boolean stopCellEditing()
        {
            return mixDelegate.stopCellEditing();
        }

        public void cancelCellEditing()
        {
            mixDelegate.cancelCellEditing();
        }

        public Component getTreeCellEditorComponent( JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row )
        {
            String stringValue = tree.convertValueToText( value, isSelected, expanded, leaf, row, false );

            mixDelegate.setValue( stringValue );

            return editorComponent;
        }

        public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column )
        {
            mixDelegate.setValue( value );

            return editorComponent;
        }

        public static void main( String[] args )
        {
            String[] splitted = "a12|b34".split( "\\|" );

            for ( String token : splitted )
            {
                System.out.println( token );
            }
        }

        public static final String SEPARATOR = "//";
        public static final String GLUE = "  ";

        protected class EditorDelegate implements ActionListener, ItemListener, Serializable
        {
            /** The value of this cell. */
            protected Object value;

            public Object getCellEditorValue()
            {
                return value;
            }

            public void setValue( Object value )
            {
                this.value = value;
            }

            public boolean isCellEditable( EventObject anEvent )
            {
                if ( anEvent instanceof MouseEvent )
                {
                    return ((MouseEvent) anEvent).getClickCount() >= clickCountToStart;
                }
                return true;
            }

            public boolean shouldSelectCell( EventObject anEvent )
            {
                return true;
            }

            public boolean startCellEditing( EventObject anEvent )
            {
                return true;
            }

            public boolean stopCellEditing()
            {
                fireEditingStopped();
                return true;
            }

            public void cancelCellEditing()
            {
                JGraph graph = AutomataEdgeEditor.this.graph;

                if ( graph != null )
                {
                    graph.repaint();
                }

                fireEditingCanceled();
            }

            public void actionPerformed( ActionEvent e )
            {
                AutomataEdgeEditor.this.stopCellEditing();
            }

            public void itemStateChanged( ItemEvent e )
            {
                AutomataEdgeEditor.this.stopCellEditing();
            }
        }

    }
}
